// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.chimi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.liuxinlong.api.WeChatMessageInterface;
import com.liuxinlong.common.AosException;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.BarPointBusinessEnum;
import com.liuxinlong.enums.BarPointSourceEnum;
import com.liuxinlong.enums.MessageContentTypeEnum;
import com.liuxinlong.enums.MessagePushBusinessEnum;
import com.liuxinlong.enums.NotificationSourceEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.chimi.dto.BarCardDto;
import com.liuxinlong.modules.chimi.dto.BarPointsDto;
import com.liuxinlong.modules.chimi.dto.LuckAwardBrowserDto;
import com.liuxinlong.modules.chimi.service.BarBrowseService;
import com.liuxinlong.modules.chimi.service.BarLuckDetailService;
import com.liuxinlong.modules.chimi.service.BarPointsService;
import com.liuxinlong.modules.dao.BarCardDao;
import com.liuxinlong.modules.dao.BarCarouselDao;
import com.liuxinlong.modules.dao.BarCommentDao;
import com.liuxinlong.modules.dao.BarLuckAudienceDao;
import com.liuxinlong.modules.dao.BarLuckAwardDao;
import com.liuxinlong.modules.dao.BarLuckDao;
import com.liuxinlong.modules.dao.BarLuckFlowDao;
import com.liuxinlong.modules.dao.BarPlateDao;
import com.liuxinlong.modules.dao.BarPointsDao;
import com.liuxinlong.modules.dao.BarPointsFlowDao;
import com.liuxinlong.modules.dao.BarPresentDao;
import com.liuxinlong.modules.dao.BarPresentFlowDao;
import com.liuxinlong.modules.dao.BarStatisticsDao;
import com.liuxinlong.modules.dao.DepartmentDao;
import com.liuxinlong.modules.dao.FileManageDao;
import com.liuxinlong.modules.dao.MenuDao;
import com.liuxinlong.modules.dao.NotificationDao;
import com.liuxinlong.modules.dao.ParameterDao;
import com.liuxinlong.modules.dao.RoleRightDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.dao.UserMatterDao;
import com.liuxinlong.modules.dao.UserRoleRelationDao;
import com.liuxinlong.modules.dao.UserThumbRecordDao;
import com.liuxinlong.modules.entity.BarCard;
import com.liuxinlong.modules.entity.BarCarousel;
import com.liuxinlong.modules.entity.BarComment;
import com.liuxinlong.modules.entity.BarLuck;
import com.liuxinlong.modules.entity.BarPlate;
import com.liuxinlong.modules.entity.BarPoints;
import com.liuxinlong.modules.entity.BarPointsFlow;
import com.liuxinlong.modules.entity.BarPresent;
import com.liuxinlong.modules.entity.BarStatistics;
import com.liuxinlong.modules.entity.MessageConfiguration;
import com.liuxinlong.modules.entity.Notification;
import com.liuxinlong.modules.entity.RoleRight;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.entity.UserMatter;
import com.liuxinlong.modules.entity.UserThumbRecord;
import com.liuxinlong.modules.system.service.FileManageService;
import com.liuxinlong.modules.system.service.UserService;
import com.liuxinlong.push.MessagePushService;
import com.liuxinlong.utils.IPUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.RedisUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 论坛浏览服务层接口实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022-07-18
 */
@Service
@Slf4j
public class BarBrowseServiceImpl implements BarBrowseService {

    @Autowired
    private BarCardDao barCardDao;

    @Autowired
    private BarPlateDao barPlateDao;

    @Autowired
    private BarCommentDao barCommentDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private DepartmentDao departmentDao;

    @Autowired
    private BarPointsDao barPointsDao;

    @Autowired
    private BarPointsService barPointsService;

    @Autowired
    private BarPointsFlowDao barPointsFlowDao;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private FileManageService fileManageService;

    @Autowired
    private FileManageDao fileManageDao;

    @Autowired
    private BarLuckDetailService barLuckDetailService;

    @Autowired
    private BarLuckAwardDao barLuckAwardDao;

    @Autowired
    private BarLuckAudienceDao barLuckAudienceDao;

    @Autowired
    private BarLuckFlowDao barLuckFlowDao;

    @Autowired
    private BarPresentFlowDao barPresentFlowDao;

    @Autowired
    private UserMatterDao userMatterDao;

    @Autowired
    private MenuDao menuDao;

    @Autowired
    private RoleRightDao roleRightDao;

    @Autowired
    private BarCarouselDao barCarouselDao;

    @Autowired
    private BarStatisticsDao barStatisticsDao;

    @Autowired
    private NotificationDao notificationDao;

    @Autowired
    private MessagePushService messagePushService;

    @Autowired
    private WeChatMessageInterface weChatMessageInterface;

    @Autowired
    private UserRoleRelationDao roleRelationDao;

    @Autowired
    private ParameterDao parameterDao;

    @Autowired
    private UserThumbRecordDao userThumbRecordDao;

    @Autowired
    private UserService userService;

    @Autowired
    private BarLuckDao barLuckDao;

    @Autowired
    private BarPresentDao barPresentDao;

    @Override
    public Map<String, Object> queryHomeBar() {

        // 查询顶部展示数据
        Map<String, Object> resultMap = barCardDao.getBarCardStatistic();
//        resultMap.put("today", 10);
//        resultMap.put("yesterday", 50);
//        resultMap.put("total", 100);
        resultMap.put("member", userDao.getUserCount(new HashMap<>()));

        // 查询各板块发帖信息
        List<BarPlate> barPlateList = barPlateDao.getShowPlate();
        List<Map<String, Object>> plateResultList = new ArrayList<>(barPlateList.size());
        Map<String, Map<String, Object>> cardCountMap = barCardDao.getCardCountGroupByPlate();
        for (BarPlate barPlate : barPlateList) {
            Map<String, Object> map = ObjectUtils.object2Map(barPlate);
            Map<String, Object> cardMap = cardCountMap.get(barPlate.getId());
            map.put("cardNum", ObjectUtils.isEmpty(cardMap) ? 0 : cardMap.getOrDefault("num", 0));
            plateResultList.add(map);
        }
        resultMap.put("plateInfo", plateResultList);
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String userId = current.getId();
        String currentDate = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD);
        resultMap.put("signFlag", !ObjectUtils.isEmpty(barPointsFlowDao.getSignFlow(userId, currentDate)));

        // 用户个人研值
        Map<String, Object> barPointsCache = redisUtils.getUserPointCache(userId);
        if (ObjectUtils.isEmpty(barPointsCache)) {
            BarPoints barPoints = barPointsDao.selectById(userId);
            resultMap.put("researchPoint", ObjectUtils.isEmpty(barPoints) ? 0 : barPoints.getPoints());
            Map<String, Map<String, String>> rankMap = barPointsDao.getRankMap();
            int rank = rankMap.containsKey(userId) ? Integer.valueOf(rankMap.get(userId).get("ranks")) : 0;
            resultMap.put("rank", rank);
            Map<String, Object> cache = new HashMap<>();
            cache.put("id", userId);
            cache.put("rank", rank);
            cache.put("point", ObjectUtils.isEmpty(barPoints) ? 0 : barPoints.getPoints());
            redisUtils.setUserPointCache(userId, cache);
        } else {
            resultMap.put("researchPoint", barPointsCache.get("point"));
            resultMap.put("rank", barPointsCache.get("rank"));
        }

        // 排行榜信息
        Map<String, Object> cacheMap = getRankingCache();
        // 总榜
        resultMap.put("researchPointList", JSONObject.parseArray((String) cacheMap.get("researchPointList"), Object.class));
        // 当日热榜
        resultMap.put("currentDayList", JSONObject.parseArray((String) cacheMap.get("currentDayList"), Object.class));
        // 当月热榜
        resultMap.put("currentMonthList", JSONObject.parseArray((String) cacheMap.get("currentMonthList"), Object.class));

        // 获取用户抽奖信息
        Map<String, Object> opportunityMap = barLuckDetailService.queryParticipationTime(userId, null);
        resultMap.put("canLuck", !ObjectUtils.isEmpty(opportunityMap));
        resultMap.put("luckId", !ObjectUtils.isEmpty(opportunityMap) ? opportunityMap.get("luckId") : "");
        return resultMap;
    }

    @Override
    public List<Map<String, Object>> pageCard(Map<String, Object> queryParam) {
        int startNum = (int) queryParam.get("startNum");
        List<BarCardDto> originalList = barCardDao.pageBarCardList(queryParam);
        return completeResult(originalList, startNum);
    }

    @Override
    public int getCardCount(Map<String, Object> queryParam) {
        return barCardDao.getBarCardCount(queryParam);
    }

    @Override
    public Map<String, Object> getBarCard(String id) {

        // todo 用户头像
        BarCard barCard = barCardDao.selectById(id);
        if (ObjectUtils.isEmpty(barCard)) {
            BarComment barComment = barCommentDao.selectById(id);
            if (ObjectUtils.isEmpty(barComment)) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "帖子信息不存在");
            }
            barCard = barCardDao.selectById(barComment.getCardId());
            if (ObjectUtils.isEmpty(barCard)) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "帖子信息不存在");
            }
        }
        String fileIds = barCard.getAttach();
        Set<String> fileIdList = new HashSet<>(Arrays.asList(fileIds.trim().split(",")));
        User user = userDao.selectById(barCard.getCreateUser());
        fileIdList.add(user.getPortrait());
        Map<String, Map<String, Object>> fileMap = new HashMap<>();
        if (!ObjectUtils.isEmpty(fileIdList)) {
            fileMap = fileManageDao.getFileMapByIds(fileIdList);
        }
        String currentIp = IPUtils.getCurrentIp();
        Map<String, Object> map = ObjectUtils.object2Map(barCard);
        if (StringUtils.isNotEmpty(barCard.getAttach())) {
            List<String> cardFileList = Arrays.asList(barCard.getAttach().split(","));
            List<Map<String, Object>> fileList = new ArrayList<>(cardFileList.size());
            int fileSort = 1;
            for (String fileId : cardFileList) {
                if (!fileMap.containsKey(fileId.trim())) {
                    continue;
                }
                Map<String, Object> fileInfo = new HashMap<>();
                fileInfo.put("sort", fileSort);
                fileInfo.put("id", fileId.trim());
                fileInfo.put("fileType", fileMap.get(fileId.trim()).get("fileType"));
                fileInfo.put("path", String.valueOf(fileMap.get(fileId.trim()).get("path")).replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload"));
                fileList.add(fileInfo);
                fileSort++;
            }
            map.put("attachList", fileList);
        }
        map.put("userName", user.getName());
        map.put("sn", user.getSn());
//        map.put("email", user.getEmail());
//        map.put("profile", user.getProfile());
//        map.put("nickName", user.getAbbreviationName());
        map.put("userPic",fileMap.containsKey(user.getPortrait()) ?
                String.valueOf(fileMap.get(user.getPortrait()).get("path")).replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload")
                : "");
        return map;
    }

    @Transactional
    @Override
    public void addBarCard(BarCard barCard) {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String id = SnowFlake.nextIdStr();
        barCard.setId(id);
        String createTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        barCard.setCreateTime(createTime);
        barCard.setCreateUser(current.getId());
        barCard.setSortNum(99999);
        barCard.setCommentsModify(1);
        barCardDao.insert(barCard);
        UserMatter userMatter = new UserMatter();
        userMatter.setId(SnowFlake.nextIdStr());
        userMatter.setCreateTime(createTime);
        userMatter.setContent("用户 " + current.getName() + " 发帖待审核");
        userMatter.setSourceType(1);
        userMatter.setSourceId(id);
        List<RoleRight> roleRightList = roleRightDao.queryRoleByMenu("120206");
        userMatter.setPendingRole(roleRightList.get(0).getRole());
        userMatterDao.insert(userMatter);
        List<String> userList = roleRelationDao.getUserByRoles(roleRightList.stream().map(RoleRight::getRole).collect(Collectors.toList()));
//        SystemParameter sp = parameterDao.getParameterByName(SystemConstants.CURRENT_SYSTEM_IP);
//        if (ObjectUtils.isEmpty(sp)) {
//            throw new AosException(ReturnCodes.HTTP_SYSTEM_ERROR);
//        }
//        String wechatMessage = "【RDKS提醒】\n"
//                + "审核通知\n"
//                + userMatter.getContent() + "\n"
//                + "创建人：系统\n"
//                + "时间：" + createTime + "\n"
//                + "<a href=\"" + sp.getValue() +"\">点击链接登陆>></a>";
        MessageConfiguration messageConfiguration = new MessageConfiguration();
        messageConfiguration.setBusinessType(MessagePushBusinessEnum.AUDIT.getValue());
        messageConfiguration.setContent(userMatter.getContent());
        messageConfiguration.setContentType(MessageContentTypeEnum.TEXT_CARD.getValue());
        weChatMessageInterface.pushMessage(userList, null, messageConfiguration, createTime);
        if (StringUtils.isEmpty(barCard.getAttach())) {
            return;
        }
        fileManageService.updateBusinessFile(barCard.getAttach(), id);
    }

    @Transactional
    @Override
    public void updateBarCard(BarCard barCard) {
        BarCard oldInfo = barCardDao.selectById(barCard.getId());
        if (ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "更新失败，原帖信息不存在");
        }
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (!StringUtils.equals(oldInfo.getCreateUser(), current.getId())) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "更新失败，用户无权修改该帖");
        }
        barCard.setStatus(oldInfo.getStatus());
        barCard.setSortNum(oldInfo.getSortNum());

        barCard.setUpdateTime(TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS));
        barCard.setUpdateUser(current.getId());
        barCardDao.updateById(barCard);
        fileManageService.updateBusinessFile(barCard.getAttach(), barCard.getId());
    }

    @Transactional
    @Override
    public void deleteBarCard(String id) {
        BarCard barCard = barCardDao.selectById(id);
        if (ObjectUtils.isEmpty(barCard)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "删除失败，帖子不存在！");
        }
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (!StringUtils.equals(barCard.getCreateUser(), current.getId())) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "删除失败，用户无权删除该帖");
        }
        barCard.setStatus(3);
        barCardDao.updateById(barCard);
        fileManageDao.batchInvalidFile(id);
    }

    @Override
    public List<Map<String, Object>> pageCardComment(Map<String, Object> queryParam) {
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String cardId = (String) queryParam.get("cardId");
        BarCard barCard = barCardDao.selectById(cardId);
        if (ObjectUtils.isEmpty(barCard) || (barCard.getStatus() != 1 && !StringUtils.equals(barCard.getCreateUser(), current.getId()))) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "帖子不存在");
        }
        List<BarComment> originalList = barCommentDao.pageBarCommentList(queryParam);
        int startNum = (int) queryParam.get("startNum");
        List<Map<String, Object>> resultList = completeCommentResult(originalList, startNum, barCard, current.getId());
        return resultList;
    }

    @Override
    public int getCardCommentCount(Map<String, Object> queryParam) {
        return barCommentDao.getBarCommentCount(queryParam);
    }

    @Override
    @Transactional
    public void addComment(BarComment barComment) {
        BarCard barCard = barCardDao.selectById(barComment.getCardId());
        if (ObjectUtils.isEmpty(barCard)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "评论失败，原帖信息不存在！");
        }
        int currentSort = 99999;
//        UserMatter userMatter = new UserMatter();
        String id = SnowFlake.nextIdStr();
        barComment.setId(id);
        String createTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
//        userMatter.setCreateTime(createTime);
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
//        userMatter.setContent("用户 " + current.getName() + " 评论待审核");
        if (StringUtils.isNotEmpty(barComment.getReply())) {
            BarComment mainInfo = barCommentDao.selectById(barComment.getReply());
            if (ObjectUtils.isEmpty(mainInfo)) {
                throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "回复失败，原评论不存在！");
            }
            barComment.setReplyUser(StringUtils.isNotEmpty(barComment.getReplyUser()) ? barComment.getReplyUser() : mainInfo.getCreateUser());
            currentSort = barCommentDao.getAllBarCommentSubCount(barComment.getReply(), barComment.getCardId()) + 1;
        }
//        userMatter.setId(SnowFlake.nextIdStr());
        barComment.setCreateTime(createTime);
        barComment.setStatus(1);
        barComment.setCreateUser(current.getId());
        barComment.setSortNum(currentSort);
        barCommentDao.insert(barComment);
//        userMatter.setSourceType(2);
//        userMatter.setSourceId(id);
//        List<RoleRight> roleRightList = roleRightDao.queryRoleByMenu("120306");
//        userMatter.setPendingRole(roleRightList.get(0).getRole());
//        userMatterDao.insert(userMatter);
        BarStatistics barStatistics = new BarStatistics();
        barStatistics.setId(id);
        barStatisticsDao.insert(barStatistics);
        barStatisticsDao.addComments(barComment.getCardId());
        Notification notification = new Notification();
        notification.setId(SnowFlake.nextIdStr());
        notification.setCreateTime(createTime);
        notification.setCreateUser(barComment.getCreateUser());
        notification.setSourceId(barComment.getCardId());
        User userInfo = userDao.selectById(barComment.getCreateUser());
        Notification parentNotification = new Notification();
        if (StringUtils.isNotEmpty(barComment.getReply())) {
            notification.setContent(userInfo.getName() + " 回复了你的评论 ");
            notification.setDealUser(barComment.getReplyUser());
            notification.setSourceType(NotificationSourceEnum.CHIMI_REPLY.getValue());
            parentNotification.setId(SnowFlake.nextIdStr());
            parentNotification.setCreateTime(createTime);
            parentNotification.setCreateUser(barComment.getCreateUser());
            parentNotification.setSourceId(barComment.getCardId());
            parentNotification.setContent(userInfo.getName() + " 回复了你的发帖 " + barCard.getTitle());
            parentNotification.setDealUser(barCard.getCreateUser());
            parentNotification.setSourceType(NotificationSourceEnum.CHIMI_COMMENT.getValue());
        } else {
            notification.setContent(userInfo.getName() + " 回复了你的发帖 " + barCard.getTitle());
            notification.setDealUser(barCard.getCreateUser());
            notification.setSourceType(NotificationSourceEnum.CHIMI_COMMENT.getValue());
        }
        if (!StringUtils.equals(notification.getDealUser(), current.getId())) {
            notificationDao.insert(notification);
            User targetUser = userDao.selectById(notification.getDealUser());
            Map<String, String> contentMap = new HashMap<>();
            contentMap.put("title", "您有一条新消息待查看");
            contentMap.put("description", notification.getContent());
            String content = JSON.toJSONString(contentMap);
            messagePushService.pushMessage(content, targetUser.getSn());
        }
        if (StringUtils.isNotEmpty(parentNotification.getId()) &&
                !StringUtils.equals(parentNotification.getDealUser(), current.getId()) &&
                !StringUtils.equals(parentNotification.getDealUser(), notification.getDealUser())) {
            notificationDao.insert(parentNotification);
            User cardUser = userDao.selectById(parentNotification.getDealUser());
            Map<String, String> contentMap = new HashMap<>();
            contentMap.put("title", "您有一条新消息待查看");
            contentMap.put("description", parentNotification.getContent());
            String content = JSON.toJSONString(contentMap);
            messagePushService.pushMessage(content, cardUser.getSn());
        }
        barPointsService.updateUserPoints(current.getId(), BarPointBusinessEnum.COMMENT.getValue(), 0);
    }

    @Override
    public void updateComment(BarComment barComment) {
        BarComment oldInfo = barCommentDao.selectById(barComment.getId());
        if (ObjectUtils.isEmpty(oldInfo)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，评论不存在！");
        }
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (!StringUtils.equals(oldInfo.getCreateUser(), current.getId())) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，用户无权限！");
        }
        BarCard cardInfo = barCardDao.selectById(barComment.getCardId());
        if (cardInfo.getCommentsModify() == 2) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "更新失败，评论信息不支持修改");
        }
        oldInfo.setContent(barComment.getContent());
        oldInfo.setUpdateTime(TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS));
        barCommentDao.updateById(oldInfo);
    }

    @Override
    public void deleteComment(String id) {

    }

    @Override
    @Transactional
    public void likeCard(String id) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        if (ObjectUtils.isEmpty(currentUser)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "点赞失败，用户不存在!");
        }
        BarCard barCard = barCardDao.selectById(id);
        if (ObjectUtils.isEmpty(barCard)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "点赞失败，发帖不存在!");
        }
        UserThumbRecord thumbRecord = userThumbRecordDao.getUserThumbRecord(barCard.getId(), currentUser.getId());
        if (ObjectUtils.isEmpty(thumbRecord)) {
            UserThumbRecord newRecord = new UserThumbRecord();
            newRecord.setId(SnowFlake.nextIdStr());
            newRecord.setBusinessId(id);
            newRecord.setUserId(currentUser.getId());
            newRecord.setOperateTime(TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS));
            userThumbRecordDao.insert(newRecord);
            barStatisticsDao.addLikes(id);
        } else {
            userThumbRecordDao.deleteById(thumbRecord.getId());
            barStatisticsDao.reduceLikes(id);
        }
    }

    @Override
    public void likeComment(String id) {

    }

    @Override
    @Transactional
    public Map<String, Object> userSign() {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        return barPointsService.updateUserPoints(currentUser.getId(), BarPointBusinessEnum.SIGN_IN.getValue(), 0);
    }

    @Override
    public List<Map<String, Object>> queryPointRecord(Map<String, Object> queryParam) {
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        queryParam.put("userId", currentUser.getId());
        List<BarPointsFlow> flowList = barPointsFlowDao.getPointFlow(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>();
        int sort = (int) queryParam.get("startNum");
        for (BarPointsFlow flow : flowList) {
            Map<String, Object> item = ObjectUtils.object2Map(flow);
            item.put("sort", sort);
            item.put("typeName", flow.getType() == 1 ? "获取" : "支出");
            item.put("sourceName", BarPointSourceEnum.getNameByValue(flow.getSourceType()));
            resultList.add(item);
            sort++;
        }
        return resultList;
    }

    @Override
    public int getPointRecordCount(Map<String, Object> queryParam) {
        return barPointsFlowDao.getBarPointsFlowCount(queryParam);
    }

    @Override
    public List<Map<String, Object>> queryLuckPrizeList(String luckId) {
        BarLuck barLuck = barLuckDao.selectById(luckId);
        if (ObjectUtils.isEmpty(barLuck)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "活动不存在！");
        }
        List<LuckAwardBrowserDto> detailList = barLuckAwardDao.getLuckAwardBrowserList(luckId);
        List<Map<String, Object>> resultList = new ArrayList<>();
        Map<String, Object> defaultMap = new HashMap<>();
        defaultMap.put("sortNum", 0);
        Map<String, Object> defaultImg = new HashMap<>();
        if (barLuck.getFloor() == 1) {
            BarPresent floorAward = barPresentDao.selectById(barLuck.getFloorAward());
            defaultImg.put("src", floorAward.getPicture());
            defaultImg.put("width", "20%");
            defaultImg.put("top", "15%");
            List<Map<String, Object>> imgs = new ArrayList<>();
            imgs.add(defaultImg);
            List<Map<String, Object>> defaultImgs = new ArrayList<>();
            defaultMap.put("imgs", defaultImgs);
            Map<String, Object> defaultFont = new HashMap<>();
            defaultFont.put("text", floorAward.getName());
            defaultFont.put("top", "58%");
            List<Map<String, Object>> defaultFonts = new ArrayList<>();
            defaultFonts.add(defaultFont);
            defaultMap.put("fonts", defaultFonts);
            defaultMap.put("title", floorAward.getName());
            defaultMap.put("background", "#332729");
        } else {
            defaultImg.put("src", "");
            defaultImg.put("width", "20%");
            defaultImg.put("top", "15%");
            List<Map<String, Object>> defaultImgs = new ArrayList<>();
            defaultImgs.add(defaultImg);
            defaultMap.put("imgs", defaultImgs);
            Map<String, Object> defaultFont = new HashMap<>();
            defaultFont.put("text", "北纬31度的空气");
            defaultFont.put("top", "58%");
            List<Map<String, Object>> defaultFonts = new ArrayList<>();
            defaultFonts.add(defaultFont);
            defaultMap.put("fonts", defaultFonts);
            defaultMap.put("title", "北纬31度的空气");
            defaultMap.put("background", "#332729");
        }


        resultList.add(defaultMap);
        boolean twoFlag = true;
        for (LuckAwardBrowserDto detail : detailList) {
            Map<String, Object> item = ObjectUtils.object2Map(detail);
            Map<String, Object> img = new HashMap<>();
            img.put("src", detail.getPicture());
            img.put("width", "20%");
            img.put("top", "15%");
            List<Map<String, Object>> imgs = new ArrayList<>();
            imgs.add(img);
            item.put("imgs", imgs);
            Map<String, Object> font = new HashMap<>();
            font.put("text", detail.getTitle());
            font.put("top", "58%");
            List<Map<String, Object>> fonts = new ArrayList<>();
            fonts.add(font);
            item.put("fonts", fonts);
            item.put("background", twoFlag ? "#3a312a" : "#332729");
            resultList.add(item);
            twoFlag = !twoFlag;
        }
        return resultList;
    }

    @Override
    public List<Map<String, Object>> queryCarouselList() {
        List<BarCarousel> barCarouselList = barCarouselDao.pageEffectiveBarCarouselList();
        if (ObjectUtils.isEmpty(barCarouselList)) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> resultList = new ArrayList<>(barCarouselList.size());
        Set<String> fileIdList = new HashSet<>();
        Set<String> pictureIdList = barCarouselList.stream().map(BarCarousel::getPicture).collect(Collectors.toSet());
        fileIdList.addAll(pictureIdList);
        Set<String> mobileIdList = barCarouselList.stream().map(BarCarousel::getPictureMobile).collect(Collectors.toSet());
        fileIdList.addAll(mobileIdList);
        Map<String, Map<String, Object>> fileMap = new HashMap<>();
        if (!ObjectUtils.isEmpty(fileIdList)) {
            fileMap = fileManageDao.getFileMapByIds(fileIdList);
        }
        String currentIp = IPUtils.getCurrentIp();
        for (BarCarousel carousel : barCarouselList) {
            Map<String, Object> item = ObjectUtils.object2Map(carousel);
            if (!StringUtils.isEmpty(carousel.getPicture())) {
                String filePath = fileMap.containsKey(carousel.getPicture()) ? (String) fileMap.get(carousel.getPicture()).get("path") : "";
                String path = StringUtils.isEmpty(filePath) ? "" : filePath.replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload");
                item.put("pictureUrl", path);
            }
            if (!StringUtils.isEmpty(carousel.getPictureMobile())) {
                String filePath = fileMap.containsKey(carousel.getPictureMobile()) ? (String) fileMap.get(carousel.getPictureMobile()).get("path") : "";
                String path = StringUtils.isEmpty(filePath) ? "" : filePath.replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload");
                item.put("pictureMobileUrl", path);
            }
            resultList.add(item);
        }
        return resultList;
    }

    @Override
    public void updateRankingCache(String userId) {
        Map<Object, Object> forumMap = redisUtils.getForumCache();
        if (ObjectUtils.isEmpty(forumMap)) {
            getRankingCache();
            return;
        }
        BarPoints points = barPointsDao.selectById(userId);
        List<Map<String, Object>> pointRanking = updatePointRanking();
        List<Map<String, Object>> dayRanking = updateDayRanking();
        List<Map<String, Object>> monthRanking = updateMonthRanking();

        Map<String, Object> resultMap = new HashMap<>();
        // 总积分榜
        resultMap.put("researchPointList", JSONObject.parseArray((String) forumMap.get("researchPointList"), Object.class));
        // 当月热榜
        resultMap.put("currentMonthList", JSONObject.parseArray((String) forumMap.get("currentMonthList"), Object.class));
        // 当周热榜
        resultMap.put("currentDayList", JSONObject.parseArray((String) forumMap.get("currentDayList"), Object.class));

//        return resultMap;
    }

    /**
     * 数据补全转换
     *
     * @param originList 原始数据列表
     * @param startNum   起始查询数
     * @return 补全数据
     */
    private List<Map<String, Object>> completeResult(List<BarCardDto> originList, int startNum) {
        if (ObjectUtils.isEmpty(originList)) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMap();
        Map<String, Map<String, String>> plateMap = barPlateDao.getBarPlateMap();
        Set<String> fileSet = new HashSet<>();
        fileSet.addAll(originList.stream().map(BarCardDto::getAttach).collect(Collectors.toSet()));
        fileSet.addAll(originList.stream().map(BarCardDto::getUserPic).collect(Collectors.toSet()));
        String fileIds = StringUtils.strip(fileSet.toString().replaceAll(" ", "").replaceAll(",null", "").replaceAll(",,", ","), "[]");
        Set<String> fileIdList = new HashSet<>(Arrays.asList(fileIds.trim().split(",")));
        Map<String, Map<String, Object>> fileMap = new HashMap<>();
        if (!ObjectUtils.isEmpty(fileIdList)) {
            fileMap = fileManageDao.getFileMapByIds(fileIdList);
        }
        String currentIp = IPUtils.getCurrentIp();
        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        List<String> cardList = originList.stream().map(BarCardDto::getId).collect(Collectors.toList());
        Map<String, Map<String, String>> thumbMap = userThumbRecordDao.queryUserThumbCardMap(cardList, current.getId());
//        Map<String,Map<String,String>> thumbCountMap = userThumbRecordDao.queryThumbCountMap(cardList);
        int sort = startNum + 1;
        for (BarCardDto record : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(record);
            map.put("sort", sort);
            if (StringUtils.isNotEmpty(record.getDepartment()) && departmentMap.containsKey(record.getDepartment())) {
                map.put("departmentName", departmentMap.get(record.getDepartment()).get("name"));
            }
            if (plateMap.containsKey(record.getPlate())) {
                map.put("plateName", plateMap.get(record.getPlate()).get("name"));
            }
            if (StringUtils.isNotEmpty(record.getAttach())) {
                List<String> cardFileList = Arrays.asList(record.getAttach().split(","));
                List<Map<String, Object>> fileList = new ArrayList<>(cardFileList.size());
                int fileSort = 1;
                for (String fileId : cardFileList) {
                    if (!fileMap.containsKey(fileId.trim())) {
                        continue;
                    }
                    Map<String, Object> fileInfo = new HashMap<>();
                    fileInfo.put("sort", fileSort);
                    fileInfo.put("id", fileId.trim());
                    fileInfo.put("fileType", fileMap.get(fileId.trim()).get("fileType"));
                    fileInfo.put("path", String.valueOf(fileMap.get(fileId.trim()).get("path")).replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload"));
                    fileList.add(fileInfo);
                    fileSort++;
                }
                map.put("attachList", fileList);
            }
            if (StringUtils.isNotEmpty(record.getUserPic()) && fileMap.containsKey(record.getUserPic())) {
                map.put("userPic", String.valueOf(fileMap.get(record.getUserPic()).get("path")).replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload"));
            }
            map.put("userId", record.getCreateUser());
            map.put("canModify", StringUtils.equals(current.getId(), record.getCreateUser()));
            map.put("liked", thumbMap.containsKey(record.getId()) ? "like" : null);
//            map.put("thumbsUp",thumbCountMap.containsKey(record.getId()) ? thumbCountMap.get(record.getId()).get("thumbNum") : 0);
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    /**
     * 数据补全转换
     *
     * @param originList    原始数据列表
     * @param startNum      起始查询数
     * @param barCard       发帖信息
     * @param currentUserId 当前用户
     * @return 补全数据
     */
    private List<Map<String, Object>> completeCommentResult(List<BarComment> originList, int startNum, BarCard barCard, String currentUserId) {
        if (ObjectUtils.isEmpty(originList))
            return new ArrayList<>();
//        User current = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
//        String currentUserId = current.getId();
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        int sort = startNum + 1;
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        for (BarComment record : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(record);
            map.put("sort", sort);
            String createUser = record.getCreateUser();
            Map<String, Object> userInfo = userService.queryUserBase(createUser);
            map.put("userPic", userInfo.get("fileUrl"));
            map.put("userName", userInfo.get("name"));
            map.put("userId", record.getCreateUser());
            map.put("canModify", barCard.getCommentsModify() == 1 && StringUtils.equals(currentUserId, createUser));
            if (barCard.getCommentsHidden() == 1 && !StringUtils.equals(currentUserId, createUser)) {
                map.put("content", "**********");
            }
            Map<String, Object> query = new HashMap<>();
            query.put("cardId", record.getCardId());
            query.put("commentId", record.getId());
            query.put("currentUser", currentUserId);
            query.put("startNum", 0);
            query.put("pageSize", 1000);
            List<BarComment> subCommentList = barCommentDao.pageBarCommentSubList(query);
            List<Map<String, Object>> subList = new ArrayList<>(subCommentList.size());
            if (!ObjectUtils.isEmpty(subCommentList))
                for (BarComment subComment : subCommentList) {
                    String subCreateUser = subComment.getCreateUser();
                    Map<String, Object> subUserInfo = userService.queryUserBase(subCreateUser);
                    Map<String, Object> subMap = ObjectUtils.object2Map(subComment);
                    subMap.put("userName", (userMap.get(subComment.getCreateUser())).get("name"));
                    subMap.put("replyName", (userMap.get(subComment.getReplyUser())).get("name"));
                    subMap.put("userPic", subUserInfo.get("fileUrl"));
                    subMap.put("userId", subCreateUser);
                    subMap.put("canModify", barCard.getCommentsModify() == 1 && StringUtils.equals(currentUserId, subCreateUser));
                    if (barCard.getCommentsHidden() == 1) {
                        subMap.put("content", "**********");
                    }
                    subList.add(subMap);
                }
            map.put("children", subList);
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    /**
     * 获取排行榜数据
     *
     * @return 排行榜数据
     */
    private Map<String, Object> getRankingCache() {
        Map<Object, Object> forumCacheMap = redisUtils.getForumCache();
        Map<String, Object> cacheMap = new HashMap<>();
        if (ObjectUtils.isEmpty(forumCacheMap)) {
            List<Map<String, Object>> researchPointList = generateAllRanking();
            cacheMap.put("researchPointList", JSON.toJSON(researchPointList).toString());
            List<Map<String, Object>> currentMonthList = generateMonthRanking();
            cacheMap.put("currentMonthList", JSON.toJSON(currentMonthList).toString());
            List<Map<String, Object>> currentDayList = generateWeekRanking();
            cacheMap.put("currentDayList", JSON.toJSON(currentDayList).toString());
            redisUtils.setForumCache(cacheMap);
        } else {
            if (!forumCacheMap.containsKey("researchPointList")) {
                List<Map<String, Object>> researchPointList = generateAllRanking();
                cacheMap.put("researchPointList", JSON.toJSON(researchPointList).toString());
            } else {
                cacheMap.put("researchPointList", forumCacheMap.get("researchPointList"));
            }
            if (!forumCacheMap.containsKey("currentMonthList")) {
                List<Map<String, Object>> currentMonthList = generateMonthRanking();
                cacheMap.put("currentMonthList", JSON.toJSON(currentMonthList).toString());
            } else {
                cacheMap.put("currentMonthList", forumCacheMap.get("currentMonthList"));
            }
            if (!forumCacheMap.containsKey("currentDayList")) {
                List<Map<String, Object>> currentDayList = generateWeekRanking();
                cacheMap.put("currentDayList", JSON.toJSON(currentDayList).toString());
            } else {
                cacheMap.put("currentDayList", forumCacheMap.get("currentDayList"));
            }
            redisUtils.setForumCache(cacheMap);
        }
        return cacheMap;
    }

    /**
     * 计算研值总榜
     *
     * @return 研值总榜
     */
    private List<Map<String, Object>> generateAllRanking() {
        List<BarPointsDto> pointList = barPointsDao.queryTopTen();

        // 积分榜
        Set<String> fileSet = pointList.stream().map(BarPointsDto::getUserPic).collect(Collectors.toSet());
        String fileIds = StringUtils.strip(fileSet.toString().replaceAll(" ", "").replaceAll(",null", "").replaceAll(",,", ","), "[]");

        Set<String> fileIdList = new HashSet<>(Arrays.asList(fileIds.trim().split(",")));
        Map<String, Map<String, Object>> fileMap = new HashMap<>();
        if (!ObjectUtils.isEmpty(fileIdList)) {
            fileMap = fileManageDao.getFileMapByIds(fileIdList);
        }
        String currentIp = IPUtils.getCurrentIp();
        List<Map<String, Object>> researchPointList = new ArrayList<>();
        int sort = 1;
        if (!ObjectUtils.isEmpty(pointList)) {
            for (BarPointsDto points : pointList) {
                Map<String, Object> item = ObjectUtils.object2Map(points);
                item.put("sort", sort);
                item.put("userId", points.getId());
                item.put("userPic", fileMap.containsKey(points.getUserPic()) ?
                        String.valueOf(fileMap.get(points.getUserPic()).get("path")).replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload")
                        : "");
                researchPointList.add(item);
                sort++;
            }
        }
        return researchPointList;
    }

    /**
     * 计算研值月榜
     *
     * @return 研值月榜
     */
    private List<Map<String, Object>> generateMonthRanking() {
        List<Map<String, Object>> currentMonthList = new ArrayList<>();
        List<Map<String, Object>> monthRankList = barPointsFlowDao.getTopTen(TimeUtils.getMonthFirstDay());
        int sort = 1;
        if (!ObjectUtils.isEmpty(monthRankList)) {
            for (Map<String, Object> pointMap : monthRankList) {
                Map<String, Object> item = new HashMap<>();
                item.put("sort", sort);
                item.put("points", pointMap.get("totalPoints"));
                String userId = (String) pointMap.get("userId");
                item.put("id", userId);
                item.put("userId", userId);
                Map<String, Object> userInfo = userService.queryUserBase(userId);
                item.put("userName", userInfo.get("name"));
//                item.put("sn", userInfo.get("fileUrl"));
                item.put("userPic", userInfo.get("fileUrl"));
                currentMonthList.add(item);
                sort++;
            }
        }
        return currentMonthList;
    }

    /**
     * 计算研值周榜
     *
     * @return 研值周榜
     */
    private List<Map<String, Object>> generateWeekRanking() {
        List<Map<String, Object>> currentWeekList = new ArrayList<>();
        List<Map<String, Object>> weekRankList = barPointsFlowDao.getTopTen(TimeUtils.getWeekStart());
        int sort = 1;
        if (!ObjectUtils.isEmpty(weekRankList)) {
            for (Map<String, Object> pointMap : weekRankList) {
                Map<String, Object> item = new HashMap<>();
                item.put("sort", sort);
                item.put("points", pointMap.get("totalPoints"));
                String userId = (String) pointMap.get("userId");
                item.put("id", userId);
                item.put("userId", userId);
                Map<String, Object> userInfo = userService.queryUserBase(userId);
                item.put("userName", userInfo.get("name"));
//                item.put("sn", userInfo.get("fileUrl"));
                item.put("userPic", userInfo.get("fileUrl"));
                currentWeekList.add(item);
                sort++;
            }
        }
        return currentWeekList;
    }

    private List<Map<String, Object>> updatePointRanking() {
        List<Map<String, Object>> pointRankingList = new ArrayList<>();
        return pointRankingList;
    }

    private List<Map<String, Object>> updateDayRanking() {
        List<Map<String, Object>> dayRankingList = new ArrayList<>();
        return dayRankingList;
    }

    private List<Map<String, Object>> updateMonthRanking() {
        List<Map<String, Object>> monthRankingList = new ArrayList<>();
        return monthRankingList;
    }


    private void updateRanking(int userPoints) {
        Map<String, Object> cacheMap = getRankingCache();
        List<Map<String, Object>> researchPointList = (List<Map<String, Object>>) JSONArray.parseObject((String) cacheMap.get("researchPointList"), List.class);
        if (researchPointList.size() < 10) {
            List<Map<String, Object>> newResearchPointList = generateAllRanking();
            cacheMap.put("researchPointList", JSON.toJSON(newResearchPointList).toString());
        } else {
            for (Map<String, Object> point : researchPointList) {
                if (((Integer) point.get("points")).intValue() < userPoints) {
                    List<Map<String, Object>> newResearchPointList = generateAllRanking();
                    cacheMap.put("researchPointList", JSON.toJSON(newResearchPointList).toString());
                    break;
                }
            }
        }
        List<Map<String, Object>> currentDayList = (List<Map<String, Object>>) JSONArray.parseObject((String) cacheMap.get("currentDayList"), List.class);
        if (currentDayList.size() < 10) {
            List<Map<String, Object>> newCurrentDayList = generateWeekRanking();
            cacheMap.put("currentDayList", JSON.toJSON(newCurrentDayList).toString());
        } else {
            for (Map<String, Object> point : currentDayList) {
                if (((Integer) point.get("points")).intValue() < userPoints) {
                    List<Map<String, Object>> newCurrentDayList = generateWeekRanking();
                    cacheMap.put("currentDayList", JSON.toJSON(newCurrentDayList).toString());
                    break;
                }
            }
        }
        List<Map<String, Object>> currentMonthList = (List<Map<String, Object>>) JSONArray.parseObject((String) cacheMap.get("currentMonthList"), List.class);
        if (currentMonthList.size() < 10) {
            List<Map<String, Object>> newCurrentMonthList = generateMonthRanking();
            cacheMap.put("currentMonthList", JSON.toJSON(newCurrentMonthList).toString());
        } else {
            for (Map<String, Object> point : currentMonthList) {
                if (((Integer) point.get("points")).intValue() < userPoints) {
                    List<Map<String, Object>> newCurrentMonthList = generateMonthRanking();
                    cacheMap.put("currentMonthList", JSON.toJSON(newCurrentMonthList).toString());
                    break;
                }
            }
        }
        redisUtils.setForumCache(cacheMap);
    }
}
